package service

import (
	"encoding/json"
	"fmt"
	"im/global"
	"im/mapper"
	"im/model"
	"im/model/request"
	"im/model/response"
	"im/utils"
	"math/rand"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
)

type UserService struct{}

// 登录
func (u *UserService) Login(c *gin.Context) {
	// username := c.Query("username")
	// password := c.Query("password")
	var loginReq request.LoginRequest
	if err := c.ShouldBind(&loginReq); err != nil {
		fmt.Println(err.Error())
		// global.LOG.Error("请求体解析失败: %s", zap.Any("err", err))
		response.FailWithMessage("请求体解析错误", c)
		return
	}

	loginUser := &model.User{
		Name:     loginReq.Username,
		Password: loginReq.Password,
	}
	if user, err := mapper.Login(loginUser); err != nil {
		fmt.Println(err.Error())
		// global.LOG.Error("登陆失败! 用户名不存在或者密码错误!", zap.Any("err", err))
		response.FailWithMessage("用户名不存在或者密码错误", c)

	} else {
		tokenNext(c, *user)
	}
	c.Abort()
}

// 退出
func (u *UserService) Logout(c *gin.Context) {

	token := c.GetHeader(global.TOKEN_HEADER)
	key := global.TOKEN_KEY_PROFIX + token
	_, err := global.RD.Del(global.CTX, key).Result()
	if err != nil {
		fmt.Println(err.Error())
		response.FailWithMessage("退出失败", c)

	} else {
		response.SuccessWithMessage("退出成功", c)
	}
	c.Abort()
}

// 登录以后签发jwt
func tokenNext(c *gin.Context, user model.User) {
	j := &model.JWT{SigningKey: []byte(global.SigningKey)} // 唯一签名
	var expiresTime = global.ExpiresTime
	claims := model.TokenClaims{
		ID:   user.ID,
		Name: user.Name,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(expiresTime) * time.Minute)), // 过期时间 30分钟 配置文件
			IssuedAt:  jwt.NewNumericDate(time.Now()),                                               // 签发时间
		},
	}
	// 生成 token
	accessToken, err := j.CreateToken(claims)
	// 加入 redis
	key := "user:" + accessToken
	b, _ := json.Marshal(claims)
	global.RD.Set(global.CTX, key, b, 0)
	// 生成 refresh token
	refreshToken, rtErr := j.CreateToken(request.RefreshTokenClaims{
		ID:   user.ID,
		Name: user.Name,
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(1) * time.Hour)), // 过期时间 1小时
			IssuedAt:  jwt.NewNumericDate(time.Now()),                                   // 签发时间
		},
	})
	if err != nil || rtErr != nil {
		fmt.Println(err.Error())
		// global.LOG.Error("设置登录状态失败!", zap.Any("err", err))
		response.FailWithMessage("设置登录状态失败", c)
	} else {
		response.Result(global.StatusOK, response.LoginResponse{
			User:         user,
			Token:        accessToken,
			RefreshToken: refreshToken,
		}, "登录成功", c)
	}
}

func (u *UserService) UserList(c *gin.Context) {

	data := mapper.GetUserList()
	c.JSON(200, gin.H{
		"code":    200,
		"message": "请求成功",
		"body":    data,
	})
}

func (u *UserService) UserCreate(c *gin.Context) {
	name := c.Query("name")
	password := c.Query("password")
	repassword := c.Query("repassword")

	salt := fmt.Sprintf("%06d", rand.Int31())

	if ub, _ := mapper.FindUserByName(name); ub.Name != "" {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "账号已存在，请重新注册",
			"body":    "",
		})
	} else if password != repassword {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "密码不一致",
			"body":    "",
		})
	} else {

		var userBasic model.User
		userBasic.Name = name
		md5 := utils.Md5Password(password, salt)
		userBasic.Password = md5
		userBasic.Salt = salt

		mapper.CreateUser(userBasic)
		c.JSON(200, gin.H{
			"code":    200,
			"message": "新增成功",
			"body":    "",
		})
	}
}

func (u *UserService) Detail(c *gin.Context) {
	id, _ := strconv.Atoi(c.Param("id"))
	if userBasic, err := mapper.GetUserById(uint(id)); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "用户不存在",
			"body":    "",
		})
	} else {
		c.JSON(200, gin.H{
			"code":    200,
			"message": "请求成功",
			"body":    userBasic,
		})
	}

}

func (u *UserService) UserDelete(c *gin.Context) {
	id, _ := strconv.Atoi(c.Query("id"))

	uid := uint(id)
	if _, err := mapper.GetUserById(uid); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "待删除用户不存在",
			"body":    "",
		})
	} else {

		mapper.DeleteUserById(uid)
		c.JSON(200, gin.H{
			"code":    200,
			"message": "删除成功",
			"body":    "",
		})
	}
}

func (u *UserService) UserUpdate(c *gin.Context) {
	var userBasic model.User

	if c.ShouldBind(&userBasic) != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "请求体解析错误",
			"body":    "",
		})
	} else if ub, err := mapper.UserUpdate(&userBasic); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "修改失败",
			"body":    userBasic,
		})
	} else {
		c.JSON(200, gin.H{
			"code":    200,
			"message": "修改成功过",
			"body":    ub,
		})
	}
}

func (u *UserService) UserSelectByPhone(c *gin.Context) {
	s := c.Query("phone")
	if ub, err := mapper.FindUserByPhoneNum(s); err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "手机号不存在",
			"body":    "",
		})
	} else {
		c.JSON(200, gin.H{
			"code":    200,
			"message": "查询成功",
			"body":    ub,
		})
	}
}

func (u *UserService) UserSelectByName(c *gin.Context) {
	s := c.Query("name")
	if ub, err := mapper.FindUserByName(s); err != nil {
		fmt.Println(err.Error())
		c.JSON(400, gin.H{
			"code":    400,
			"message": "用户名不存在",
			"body":    "",
		})
	} else {
		c.JSON(200, gin.H{
			"code":    200,
			"message": "查询成功",
			"body":    ub,
		})
	}
	c.Abort()
}
